home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / icdriver.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  12.5 KB  |  387 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <crtdbg.h>
  19.  
  20. #include <windows.h>
  21. #include <mmsystem.h>
  22. #include <vfw.h>
  23.  
  24. //#include "msviddrv.h"
  25.  
  26.  
  27.  
  28. #include "IVideoDriver.h"
  29. #include "IVideoCompressor.h"
  30.  
  31. #include "yuvcodec.h"
  32.  
  33. #define BOGUS_DRIVER_ID     1
  34.  
  35. static IVideoDriver *videoDrivers[] = {
  36.  
  37.     // add other procedures here...
  38.  
  39.     &g_YUVCodecDriver,
  40.  
  41.     NULL              // FENCE: must be last
  42. };
  43.  
  44. /***************************************************************************
  45.  ***************************************************************************/
  46.  
  47. class DriverPtrTranslator {
  48. public:
  49.     DriverPtrTranslator *next, *prev;
  50.     DWORD id16;
  51.     IVideoCompressor *id32;
  52. };
  53.  
  54. static DriverPtrTranslator *active_opens = NULL;
  55. static DWORD xlat_last_id = 2;
  56.  
  57. static DriverPtrTranslator *find_xlator_by_driverptr(IVideoCompressor *ivc) {
  58.     DriverPtrTranslator *ptr = active_opens;
  59.  
  60.     while(ptr) {
  61.         if (ivc == ptr->id32) return ptr;
  62.  
  63.         ptr = ptr->next;
  64.     }
  65.  
  66.     return NULL;
  67. }
  68.  
  69. static DriverPtrTranslator *find_xlator_by_id16(DWORD id16) {
  70.     DriverPtrTranslator *ptr = active_opens;
  71.  
  72.     while(ptr) {
  73.         if (id16 == ptr->id16) return ptr;
  74.  
  75.         ptr = ptr->next;
  76.     }
  77.  
  78.     return NULL;
  79. }
  80.  
  81. static IVideoCompressor *id_to_driverptr(DWORD id16) {
  82.     DriverPtrTranslator *dpt = find_xlator_by_id16(id16);
  83.  
  84.     return dpt ? dpt->id32 : NULL;
  85. }
  86.  
  87. static DriverPtrTranslator *create_translation() {
  88.     DWORD start_id = xlat_last_id;
  89.     DWORD cur_id = start_id;
  90.  
  91.     do {
  92.         if (cur_id != BOGUS_DRIVER_ID && cur_id) {
  93.             if (!find_xlator_by_id16(cur_id)) {
  94.                 DriverPtrTranslator *dpt;
  95.  
  96.                 if (!(dpt = new DriverPtrTranslator)) return 0;
  97.  
  98.                 dpt->prev = NULL;
  99.                 dpt->next = active_opens;
  100.                 dpt->id16 = cur_id;
  101.  
  102.                 start_id = (cur_id+1) & 0xffff;
  103.  
  104.                 if (active_opens) active_opens->prev = dpt;
  105.                 active_opens = dpt;
  106.  
  107.                 return dpt;
  108.             }
  109.         }
  110.  
  111.         cur_id = (cur_id+1) & 0xffff;
  112.     } while(cur_id != start_id);
  113.  
  114.     return 0;
  115. }
  116.  
  117. void remove_translation(DriverPtrTranslator *dpt) {
  118.     if (dpt == active_opens) active_opens = dpt->next;
  119.     if (dpt->prev) dpt->prev->next = dpt->next;
  120.     if (dpt->next) dpt->next->prev = dpt->prev;
  121.  
  122.     delete dpt;
  123. }
  124.  
  125. ////////////////////////////////////////////////////////////
  126.  
  127. #ifdef _DEBUG
  128.  
  129. #define DRIVERMESSAGE(x) x,#x
  130.  
  131. static struct DriveMessageTranslation {
  132.     UINT msg;
  133.     char *name;
  134. } driverMessages[]={
  135.     DRIVERMESSAGE(DRV_LOAD),
  136.     DRIVERMESSAGE(DRV_FREE),
  137.     DRIVERMESSAGE(DRV_OPEN),
  138.     DRIVERMESSAGE(DRV_CLOSE),
  139.     DRIVERMESSAGE(DRV_QUERYCONFIGURE),
  140.     DRIVERMESSAGE(DRV_CONFIGURE),
  141.     DRIVERMESSAGE(DRV_DISABLE),
  142.     DRIVERMESSAGE(DRV_ENABLE),
  143.     DRIVERMESSAGE(DRV_INSTALL),
  144.     DRIVERMESSAGE(DRV_REMOVE),
  145.     DRIVERMESSAGE(ICM_ABOUT),
  146.     DRIVERMESSAGE(ICM_COMPRESS),
  147.     DRIVERMESSAGE(ICM_COMPRESS_BEGIN),
  148.     DRIVERMESSAGE(ICM_COMPRESS_END),
  149.     DRIVERMESSAGE(ICM_COMPRESS_FRAMES_INFO),
  150.     DRIVERMESSAGE(ICM_COMPRESS_GET_FORMAT),
  151.     DRIVERMESSAGE(ICM_COMPRESS_GET_SIZE),
  152.     DRIVERMESSAGE(ICM_COMPRESS_QUERY),
  153.     DRIVERMESSAGE(ICM_CONFIGURE),
  154.     DRIVERMESSAGE(ICM_DECOMPRESS),
  155.     DRIVERMESSAGE(ICM_DECOMPRESS_BEGIN),
  156.     DRIVERMESSAGE(ICM_DECOMPRESS_END),
  157.     DRIVERMESSAGE(ICM_DECOMPRESS_GET_FORMAT),
  158.     DRIVERMESSAGE(ICM_DECOMPRESS_GET_PALETTE),
  159.     DRIVERMESSAGE(ICM_DECOMPRESS_QUERY),
  160.     DRIVERMESSAGE(ICM_DECOMPRESS_SET_PALETTE),
  161.     DRIVERMESSAGE(ICM_DECOMPRESSEX),
  162.     DRIVERMESSAGE(ICM_DECOMPRESSEX_BEGIN),
  163.     DRIVERMESSAGE(ICM_DECOMPRESSEX_QUERY),
  164.     DRIVERMESSAGE(ICM_DRAW),
  165.     DRIVERMESSAGE(ICM_DRAW_BEGIN),
  166.     DRIVERMESSAGE(ICM_DRAW_CHANGEPALETTE),
  167.     DRIVERMESSAGE(ICM_DRAW_END),
  168.     DRIVERMESSAGE(ICM_DRAW_FLUSH),
  169.     DRIVERMESSAGE(ICM_DRAW_GETTIME),
  170.     DRIVERMESSAGE(ICM_DRAW_QUERY),
  171.     DRIVERMESSAGE(ICM_DRAW_REALIZE),
  172.     DRIVERMESSAGE(ICM_DRAW_RENDERBUFFER),
  173.     DRIVERMESSAGE(ICM_DRAW_SETTIME),
  174.     DRIVERMESSAGE(ICM_DRAW_START),
  175.     DRIVERMESSAGE(ICM_DRAW_START_PLAY),
  176.     DRIVERMESSAGE(ICM_DRAW_STOP),
  177.     DRIVERMESSAGE(ICM_DRAW_STOP_PLAY),
  178.     DRIVERMESSAGE(ICM_DRAW_SUGGESTFORMAT),
  179.     DRIVERMESSAGE(ICM_DRAW_WINDOW),
  180.     DRIVERMESSAGE(ICM_GET),
  181.     DRIVERMESSAGE(ICM_GETBUFFERSWANTED),
  182.     DRIVERMESSAGE(ICM_GETDEFAULTKEYFRAMERATE),
  183.     DRIVERMESSAGE(ICM_GETDEFAULTQUALITY),
  184.     DRIVERMESSAGE(ICM_GETINFO),
  185.     DRIVERMESSAGE(ICM_GETQUALITY),
  186.     DRIVERMESSAGE(ICM_GETSTATE),
  187.     DRIVERMESSAGE(ICM_SET_STATUS_PROC),
  188.     DRIVERMESSAGE(ICM_SETQUALITY),
  189.     DRIVERMESSAGE(ICM_SETSTATE),
  190. };
  191.  
  192. static char *TranslateDriverMessage(UINT msg) {
  193.     static char buf[12];
  194.  
  195.     for(int i=0; i<(sizeof driverMessages/sizeof driverMessages[0]); i++)
  196.         if (driverMessages[i].msg == msg)
  197.             return driverMessages[i].name;
  198.  
  199.     wsprintf(buf, "%08lx", msg);
  200.  
  201.     return buf;
  202. }
  203.  
  204. #endif
  205.  
  206. /////////////////////
  207.  
  208. LRESULT CALLBACK VCMDriverProc(DWORD dwDriverID, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2)
  209. {
  210.     IVideoCompressor *pi;
  211.     int        i;
  212.     LRESULT dw;
  213.  
  214.     if ( (dwDriverID == BOGUS_DRIVER_ID) || (dwDriverID == 0))
  215.         pi = NULL;
  216.     else
  217.         pi = (IVideoCompressor *)id_to_driverptr(dwDriverID);
  218.  
  219. #ifdef _DEBUG
  220.     _RPT4(0,"Driver %08lx, Message %s(%08lx, %08lx)\n", dwDriverID, TranslateDriverMessage(uiMessage), lParam1, lParam2);
  221. #endif
  222.  
  223.     switch (uiMessage)
  224.     {
  225.         case DRV_LOAD:
  226.  
  227.             for(i=0; videoDrivers[i]; i++)
  228.                 if (!videoDrivers[i]->Load(hDriver))
  229.                     return 0L;
  230.         
  231.             return (LRESULT)1L;
  232.  
  233.         case DRV_FREE:
  234.  
  235.             // put global de-initialization here...
  236.  
  237.         // Pass to all driver procs
  238.             for(i=0; videoDrivers[i]; i++)
  239.                 videoDrivers[i]->Free(hDriver);
  240.         
  241.             return (LRESULT)1L;
  242.  
  243.         case DRV_OPEN:
  244.              
  245.             /*
  246.                Sent to the driver when it is opened. 
  247.  
  248.                dwDriverID is 0L.
  249.                
  250.                lParam1 is a far pointer to a zero-terminated string
  251.                containing the name used to open the driver.
  252.                
  253.                lParam2 is passed through from the drvOpen call. It is
  254.                NULL if this open is from the Drivers Applet in control.exe
  255.                It is LPVIDEO_OPEN_PARMS otherwise.
  256.                 
  257.                Return 0L to fail the open.
  258.              */
  259.  
  260.             //
  261.             //  if we were opened without an open structure then just
  262.             //  return a phony (non zero) id so the OpenDriver() will
  263.             //  work.
  264.             //
  265.  
  266.             if (lParam2 == 0)
  267.                 return BOGUS_DRIVER_ID;
  268.  
  269.             // else, ask all procs if they like input type
  270.             {
  271.                 DriverPtrTranslator *dpt = create_translation();
  272.  
  273.                 for (i=0; videoDrivers[i]; i++) {
  274.                     if (dw = (DWORD)videoDrivers[i]->Open(hDriver, (char *)lParam1, (LPVIDEO_OPEN_PARMS)lParam2)) {
  275.                         _RPT2(0,"DRV_OPEN: Driver %d returned %p\n", i, dw);
  276.  
  277.                         dpt->id32 = (IVideoCompressor *)dw;
  278.  
  279.                         return dpt->id16;    // they did, return
  280.                     }
  281.                 }
  282.  
  283.                 remove_translation(dpt);
  284.             }
  285.         
  286.             return 0L;
  287.  
  288.         case DRV_CLOSE:
  289.  
  290.             if (pi) {
  291.                 DriverPtrTranslator *dpt;
  292.  
  293.                 if (dpt = find_xlator_by_id16(dwDriverID))
  294.                     remove_translation(dpt);
  295.  
  296.                 delete pi;
  297.             }
  298.  
  299.             return 0L;
  300.  
  301.         case DRV_QUERYCONFIGURE:
  302.             return (LRESULT)0L;
  303.  
  304.         case DRV_CONFIGURE:        
  305.             return DRV_OK;
  306.  
  307.         /*********************************************************************
  308.  
  309.             standard driver messages
  310.  
  311.         *********************************************************************/
  312.  
  313.         case DRV_DISABLE:
  314.             for(i=0; videoDrivers[i]; i++)
  315.                 videoDrivers[i]->Disable(hDriver);
  316.  
  317.             return TRUE;
  318.  
  319.         case DRV_ENABLE:
  320.             for(i=0; videoDrivers[i]; i++)
  321.                 videoDrivers[i]->Enable(hDriver);
  322.  
  323.             return TRUE;
  324.  
  325.         case DRV_INSTALL:
  326.         case DRV_REMOVE:
  327.             return (LRESULT)DRV_OK;
  328.  
  329.         default:
  330.  
  331.             // HACK!!
  332.  
  333.             if (uiMessage == ICM_GETINFO)
  334.                 return ((YUVCodec *)pi)->YUVCodec::GetInfo((ICINFO *)lParam1, (DWORD)lParam2);
  335.  
  336.             if (pi && uiMessage>=DRV_USER) switch(uiMessage) {
  337.                 case ICM_ABOUT:                        return pi->About((HWND)lParam1);
  338.                 case ICM_COMPRESS:                    return pi->Compress((ICCOMPRESS *)lParam1, (DWORD)lParam2);
  339.                 case ICM_COMPRESS_BEGIN:            return pi->CompressBegin((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  340.                 case ICM_COMPRESS_FRAMES_INFO:        return pi->CompressFramesInfo((ICCOMPRESSFRAMES *)lParam1, (DWORD)lParam2);
  341.                 case ICM_COMPRESS_GET_FORMAT:        return pi->CompressGetFormat((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  342.                 case ICM_COMPRESS_GET_SIZE:            return pi->CompressGetSize((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  343.                 case ICM_COMPRESS_QUERY:            return pi->CompressQuery((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  344.                 case ICM_CONFIGURE:                    return pi->Configure((HWND)lParam1);
  345.                 case ICM_DECOMPRESS:                return pi->Decompress((ICDECOMPRESS *)lParam1, (DWORD)lParam2);
  346.                 case ICM_DECOMPRESS_BEGIN:            return pi->DecompressBegin((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  347.                 case ICM_DECOMPRESS_END:            return pi->DecompressEnd();
  348.                 case ICM_DECOMPRESS_GET_FORMAT:        return pi->DecompressGetFormat((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  349.                 case ICM_DECOMPRESS_GET_PALETTE:    return pi->DecompressGetPalette((LPBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2);
  350.                 case ICM_DECOMPRESS_QUERY:            return pi->DecompressQuery((LPBITMAPINFO)lParam1, (LPBITMAPINFO)lParam2);
  351.                 case ICM_DECOMPRESS_SET_PALETTE:    return pi->DecompressSetPalette((LPBITMAPINFOHEADER)lParam1);
  352.                 case ICM_DECOMPRESSEX:                return pi->DecompressEx((ICDECOMPRESSEX *)lParam1, (DWORD)lParam2);
  353.                 case ICM_DECOMPRESSEX_BEGIN:        return pi->DecompressExBegin((ICDECOMPRESSEX *)lParam1, (DWORD)lParam2);
  354.                 case ICM_DECOMPRESSEX_QUERY:        return pi->DecompressExQuery((ICDECOMPRESSEX *)lParam1, (DWORD)lParam2);
  355.                 case ICM_DRAW:                        return pi->Draw((ICDRAW *)lParam1, (DWORD)lParam2);
  356.                 case ICM_DRAW_BEGIN:                return pi->DrawBegin((ICDRAWBEGIN *)lParam1, (DWORD)lParam2);
  357.                 case ICM_DRAW_CHANGEPALETTE:        return pi->DrawChangePalette((BITMAPINFO *)lParam1);
  358.                 case ICM_DRAW_END:                    return pi->DrawEnd();
  359.                 case ICM_DRAW_FLUSH:                return pi->DrawFlush();
  360.                 case ICM_DRAW_GETTIME:                return pi->DrawGetTime((DWORD *)lParam1);
  361.                 case ICM_DRAW_QUERY:                return pi->DrawQuery((BITMAPINFO *)lParam1);
  362.                 case ICM_DRAW_REALIZE:                return pi->DrawRealize((HDC)lParam1, (BOOL)lParam2);
  363.                 case ICM_DRAW_RENDERBUFFER:            return pi->DrawRenderBuffer();
  364.                 case ICM_DRAW_SETTIME:                return pi->DrawSetTime((DWORD)lParam1);
  365.                 case ICM_DRAW_START:                return pi->DrawStart();
  366.                 case ICM_DRAW_START_PLAY:            return pi->DrawStartPlay((DWORD)lParam1, (DWORD)lParam2);
  367.                 case ICM_DRAW_STOP:                    return pi->DrawStop();
  368.                 case ICM_DRAW_STOP_PLAY:            return pi->DrawStopPlay();
  369.                 case ICM_DRAW_SUGGESTFORMAT:        return pi->DrawSuggestFormat((ICDRAWSUGGEST *)lParam1, (DWORD)lParam2);
  370.                 case ICM_DRAW_WINDOW:                return pi->DrawWindow((RECT *)lParam1);
  371.                 case ICM_GET:                        return pi->Get((LPVOID)lParam1, (DWORD)lParam2);
  372.                 case ICM_GETBUFFERSWANTED:            return pi->GetBuffersWanted((DWORD *)lParam1);
  373.                 case ICM_GETDEFAULTKEYFRAMERATE:    return pi->GetDefaultKeyFrameRate((DWORD *)lParam1);
  374.                 case ICM_GETDEFAULTQUALITY:            return pi->GetDefaultQuality((DWORD *)lParam1);
  375.                 case ICM_GETINFO:                    return pi->GetInfo((ICINFO *)lParam1, (DWORD)lParam2);
  376.                 case ICM_GETQUALITY:                return pi->GetQuality((DWORD *)lParam1);
  377.                 case ICM_GETSTATE:                    return pi->GetState((LPVOID)lParam1, (DWORD)lParam2);
  378.                 case ICM_SET_STATUS_PROC:            return pi->SetStatusProc((ICSETSTATUSPROC *)lParam1, (DWORD)lParam2);
  379.                 case ICM_SETQUALITY:                return pi->SetQuality((DWORD *)lParam1);
  380.                 case ICM_SETSTATE:                    return pi->SetState((LPVOID)lParam1, (DWORD)lParam2);
  381.                 default:
  382.                     return pi->Default(dwDriverID, hDriver, uiMessage, lParam1, lParam2);
  383.             } else
  384.                 return DefDriverProc(dwDriverID, hDriver, uiMessage, lParam1, lParam2);
  385.     }
  386. }
  387.